/**
 * 
 */
package model.session;

import java.io.BufferedWriter;
import java.io.IOException;

import controller.xml.XMLBaliseFormat;

/**
 * <p>
 * A session block is a element of a chain of event that append in a session.
 * </p>
 * <p>
 * It possess a status and a first block. This first characterizes a session, usually it is a
 * {@link CNFUse}
 * </p>
 * 
 * @author GRONOWSKI Stephane svan001@aol.com
 * 
 * 
 * 
 *         igsat 2010
 * 
 */
public class SessionBlock {

	protected SessionBlock	first;
	protected long			previousExecutionTime	= 0;

	/**
	 * create a session block with the first block of the session.
	 * 
	 * @param first
	 *            the first block of the session
	 */
	public SessionBlock(SessionBlock first) {
		if (first == null)
			throw new IllegalArgumentException();

		this.first = first;
	}

	/**
	 * create a session block using for first itself.
	 */
	public SessionBlock() {
		first = this;
	}

	/**
	 * Return the first block.
	 * 
	 * @return the first block.
	 */
	public SessionBlock getFirst() {
		return first;
	}

	/**
	 * Set the first block.
	 * 
	 * @param first
	 *            the first to set
	 */
	public void setFirst(SessionBlock first) {
		this.first = first;
	}

	/**
	 * Return the previousExecutionTime : means execution time needed to get to this session block.
	 * 
	 * @return the previousExecutionTime
	 */
	public long getPreviousExecutionTime() {
		return previousExecutionTime;
	}

	/**
	 * Set the previousExecutionTime : means execution time needed to get to this session block.
	 * 
	 * @param previousExecutionTime
	 *            the previousExecutionTime to set
	 */
	public void setPreviousExecutionTime(long previousExecutionTime) {
		this.previousExecutionTime = previousExecutionTime;
	}

	/**
	 * Return the total amount time needed to get from the first block to this and its eventual
	 * execution result : means like execution time of all the preprocessor from the first to the
	 * end of the {@link ExecutableSessionBlock} or for a {@link CNFUse} this is the same as
	 * getPreviousExecutiontime.
	 * 
	 * @return the total amount time needed to get from the first block to the execution result
	 */
	public long getTotalExecutionTime() {
		return getPreviousExecutionTime();
	}

	/**
	 * Return the total execution time in "human form" example: "3ms", "3s", "3h4m".
	 * 
	 * @return how much time the program was running.
	 */
	public String getHumanTotalExecutionTime() {
		long time = getTotalExecutionTime();

		long h = time / 3600000;
		time %= 3600000;
		long m = time / 60000;
		time %= 60000;
		long s = time / 1000;
		time %= 1000;
		long ms = time;

		String res = "";
		if (h != 0)
			res = h + "h";
		if (m != 0)
			res += m + "m ";
		if (s != 0)
			res += s + "s ";
		if (ms != 0)
			res += ms + "ms";
		if (res.isEmpty())
			res = "none";

		return res;
	}

	/**
	 * Export the data in XML
	 * 
	 * @param file
	 *            {@link BufferedWriter} to write
	 * @throws IOException
	 */
	public void exportXML(BufferedWriter file) throws IOException {

		// open
		// file.newLine();
		file.write("<" + XMLBaliseFormat.SESSION_BLOCK + ">");

		// previous time
		// file.newLine();
		file.write("<" + XMLBaliseFormat.PREVIOUS_TIME + ">");
		file.write(String.valueOf(previousExecutionTime));
		file.write("</" + XMLBaliseFormat.PREVIOUS_TIME + ">");

		// close
		// file.newLine();
		file.write("</" + XMLBaliseFormat.SESSION_BLOCK + ">");
	}
}
